﻿/* Copyright 2010 Igor Francé
 * 
 * This file is part of ECMADoc (http://ecmadoc.codeplex.com).
 * 
 * ECMADoc is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 * 
 * ECMADoc is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with ECMADoc. 
 * If not, see http://www.gnu.org/licenses/.
 */
namespace EcmaDoc.Core.Items
{
	using System;
	using System.Xml;

	using EcmaDoc.Core.Configuration;

	/// <summary>
	/// Represents a namespace code item.
	/// </summary>
	public class NamespaceItem : CodeItem
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="NamespaceItem"/> class, using the specified
		/// <paramref name="parentItem"/> and <paramref name="name"/>.
		/// </summary>
		/// <param name="parentItem">The parent item that this code item belongs to.</param>
		/// <param name="name">The name of this namespace item.</param>
		public NamespaceItem(CodeItem parentItem, string name)
			: this(parentItem, name, (Comment) null)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="NamespaceItem"/> class, using the specified
		/// <paramref name="parentItem"/>, <paramref name="name"/> and <paramref name="commentString"/>.
		/// </summary>
		/// <param name="parentItem">The parent item that this code item belongs to.</param>
		/// <param name="name">The name of this namespace item.</param>
		/// <param name="commentString">The comment string for this namespace item.</param>
		public NamespaceItem(CodeItem parentItem, string name, string commentString)
			: this(parentItem, name, (Comment) null)
		{
			this.Comment = Comment.Create(commentString, this);
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="NamespaceItem"/> class, using the specified
		/// <paramref name="parentItem"/>, <paramref name="name"/> and <paramref name="comment"/>.
		/// </summary>
		/// <param name="parentItem">The parent item that this code item belongs to.</param>
		/// <param name="name">The name of this namespace item.</param>
		/// <param name="comment">The parsed comment for this namespace item.</param>
		public NamespaceItem(CodeItem parentItem, string name, Comment comment)
			: base(parentItem, name, comment)
		{
			ItemType = ItemType.Namespace;
		}

		/// <summary>
		/// Gets the documentation URL of this code item.
		/// </summary>
		public override string Url
		{
			get
			{
				string extension = this.OwnerProject.Info.FileExtension;
				string itemName = CodeItem.GetValidFileName(this.Name);
				return "N." + itemName + extension;
			}
		}

		/// <summary>
		/// Gets the name of this item.
		/// </summary>
		public override string Name
		{
			get
			{
				return this.FullName;
			}
		}

		/// <summary>
		/// Gets the prefix of this code item's name (for instance <c>wl.modules</c> for full name <c>wl.modules.TwitterModule</c>).
		/// </summary>
		public override string NamePrefix
		{
			get
			{
				return string.Empty;
			}
		}

		/// <summary>
		/// Gets the dynamic name, comprised of all parent items.
		/// </summary>
		/// <value>
		/// The value returned will be in a format similar to <c>[Document].[Namespace].[Class].[Member]</c>.
		/// </value>
		public override string ExpandedName
		{
			get
			{
				return this.FullName;
			}
		}

		/// <summary>
		/// Gets the name of this item as it will be saved when creating the XML element that represents this item.
		/// </summary>
		public override string XmlItemName
		{
			get
			{
				return FullName;
			}
		}

		/// <summary>
		/// Adds the specified <paramref name="member"/> with the specified <paramref name="visibility"/> and 
		/// <paramref name="memberName"/>.
		/// </summary>
		/// <param name="memberName">The name of the member being added.</param>
		/// <param name="visibility">The visibility of the member being added.</param>
		/// <param name="member">The member being added.</param>
		/// <returns>The member that got added.</returns>
		public override CodeItem AddMember(string memberName, Visibility visibility, CodeItem member)
		{
			if (visibility != Visibility.Private)
				visibility = Visibility.Public;

			if (member.RawName == this.RawName)
			{
				if (this.Comment == null && member.Comment != null)
				{
					this.Comment = Comment.Create(member.Comment.RawString, this);
				}

				return this;
			}

			return base.AddMember(memberName, visibility, member);
		}

		/// <summary>
		/// Creates an XML node that represents this item.
		/// </summary>
		/// <param name="document">The owner document to use for creating the node.</param>
		/// <param name="processChildren">If set to <c>true</c>, the child members will be appended as xml elements too.</param>
		/// <returns>An XML node that represents this item.</returns>
		internal override XmlElement ToXml(XmlDocument document, bool processChildren)
		{
			XmlElement self = base.ToXml(document, processChildren);

			// add the sort attribute to enable xsl to easily render the global namespace 
			// in front of other namespaces, without knowing anything about the structure
			self.SetAttribute("sort", this.Name == ParserConfig.GlobalNamespace ? "1" : "2");

			return self;
		}
	}
}
